%{
	
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
typedef struct{
	int tipo;
	char *conteudo;
} node;
*/
//#define YYSTYPE node*

char messages[1000] = ""; 

unsigned int lc = 1;
unsigned int ln;
unsigned int ncol = 1;

int ha_erro=0;

int retorno(int  valor_token, int tamanho){
	ncol+= tamanho;
	return valor_token;
}

void mensagemErro(char *message, unsigned int ln) {
	char buffer[50];
	sprintf(buffer, "Erro na linha %i %s.\n", ln, message);
	strcat(messages, buffer);
	ha_erro=1;
}
 
void mostrarMensagens() {
	if(strlen(messages) > 0){
		printf("\n%s", messages);
	}

	printf("%d linhas\n%d colunas\n", lc,ncol);
} 

%}

caractere		\'.\'
flutuante		[+-]?[0-9]+\.[0-9]+([eE][+-]?[0-9]{1,2})?
inteiro			[+-]?[0-9]+
identificador	[a-zA-Z][a-zA-Z0-9_]*
espaco			[ \t]+
erro			.

%x comentario string


%%

[pP]rogram|PROGRAM		{return retorno(PROGRAM,yyleng);}
[pP]rocedure|PROCEDURE	{return retorno(PROCEDURE,yyleng);}
[fF]unction|FUNCTION	{return retorno(FUNCTION,yyleng);}
[cC]onst|CONST			{return retorno(CONST,yyleng);}
[tT]ype|TYPE			{return retorno(TYPE,yyleng);}
[vV]ar|VAR				{return retorno(VAR,yyleng);}
[aA]rray|ARRAY			{return retorno(ARRAY,yyleng);}
[bB]oolean|BOOLEAN		{return retorno(BOOLEAN,yyleng);}
[cC]har|CHAR			{return retorno(CHAR,yyleng);}
[iI]nteger|INTEGER		{return retorno(INTEGER,yyleng);}
[rR]eal|REAL			{return retorno(REAL,yyleng);}
[rR]ecord|RECORD		{return retorno(RECORD,yyleng);}
[bB]egin|BEGIN			{return retorno(BEGIN_,yyleng);}
[eE]nd|END				{return retorno(END,yyleng);}
[oO]f|OF				{return retorno(OF,yyleng);}
[iI]f|IF				{return retorno(IF,yyleng);}
[tT]hen|THEN			{return retorno(THEN,yyleng);}
[eE]lse|ELSE			{return retorno(ELSE,yyleng);}
[fF]or|FOR				{return retorno(FOR,yyleng);}
[tT]o|TO				{return retorno(TO,yyleng);}
[dD]own[tT]o|DOWNTO		{return retorno(DOWNTO,yyleng);}
[dD]o|DO				{return retorno(DO,yyleng);}
[nN]ew|NEW				{return retorno(NEW,yyleng);}
[dD]ispose|DISPOSE		{return retorno(DISPOSE,yyleng);}
\,						{return retorno(VIRGULA,yyleng);}
\;						{return retorno(PONTO_E_VIRGULA,yyleng);}
\:						{return retorno(DOIS_PONTOS,yyleng);}
".."					{return retorno(OPERADOR_DE_SUBFAIXA,yyleng);}
\.						{return retorno(PONTO, yyleng);}
":="					{return retorno(OPERADOR_DE_ATRIBUICAO,yyleng);}
\+						{return retorno(SOMA,yyleng);}
\-						{return retorno(SUBTRACAO,yyleng);}
\*						{return retorno(ASTERISCO,yyleng);}
\/						{return retorno(DIVISAO,yyleng);}
\@						{return retorno(ENDERECO,yyleng);}
\^						{return retorno(VALOR_DE_PONTEIRO,yyleng);}
[mM]od|MOD				{return retorno(MOD,yyleng);}
[aA]nd|AND				{return retorno(AND,yyleng);}
[oO]r|OR				{return retorno(OR,yyleng);}
[nN]ot|NOT				{return retorno(NOT,yyleng);}
\=						{return retorno(IGUALDADE,yyleng);}
"<>"					{return retorno(DESIGUALDADE,yyleng);}
\< 						{return retorno(MENOR,yyleng);}
"<="					{return retorno(MENOR_OU_IGUAL,yyleng);}
\>						{return retorno(MAIOR,yyleng);}
">="					{return retorno(MAIOR_OU_IGUAL,yyleng);}
\(						{return retorno(ABRE_PARENTESIS,yyleng);}
\)						{return retorno(FECHA_PARENTESIS,yyleng);}
"["						{return retorno(ABRE_COLCHETE,yyleng);}
"]"						{return retorno(FECHA_COLCHETE,yyleng);}
"?"						{return retorno(CONDICIONAL_TERNARIO,yyleng);}
\n						{++lc;ncol=0;}
\0						{return retorno(FIM_DE_ARQUIVO,yyleng);}	
[tT]rue|TRUE			{return retorno(VALOR_BOOL,yyleng);}
[fF]alse|FALSE			{return retorno(VALOR_BOOL,yyleng);}
[wW]hile|WHILE			{return retorno(WHILE, yyleng);}
[bB]reak|BREAK			{return retorno(BREAK, yyleng);}
[gG]o[tT]o|GOTO			{return retorno(GOTO, yyleng);}
[rR]epeat|REPEAT		{return retorno(REPEAT, yyleng);}
[sS]tep|STEP			{return retorno(STEP, yyleng);}


\{								{BEGIN(comentario); ln = lc;}
<comentario>[^\{\}\n<EOF>]*		;
<comentario>\n					++lc;
<comentario><<EOF>>				{mensagemErro("Comentário não terminado", ln); yyterminate( );}
<comentario>\}					BEGIN(INITIAL);


\"							{BEGIN string; ln = lc;}
<string>[^\"\n<<EOF>>]*		;
<string>\n					++lc;
<string><<EOF>>				{mensagemErro("String não terminada", ln); yyterminate( );}
<string>\"					{BEGIN INITIAL; printf("VALOR_STRING");}

{caractere}				{yylval = yytext; return retorno(VALOR_CHAR, yyleng);}
{flutuante}				{yylval = yytext; return retorno(VALOR_FLOAT, yyleng);}
{inteiro}				{yylval = yytext; return retorno(VALOR_INT, yyleng);}
{identificador}			{yylval = yytext; return retorno(IDENTIFICADOR, yyleng);}
{espaco}				{ncol+=1;}
{erro}					mensagemErro("Identificador inválido", lc);

%%
int yywrap() {
	return 1;
}
